#pragma once

#include <hash_map>
#include "yyparser.h"

class ReservedWordDictionary
{
public:
    ReservedWordDictionary()
    {
        // these constants must be consistent with those in yyparse.h

#define ADD_KEYWORD( X ) \
    dict[#X] = T_SQL_##X

        ADD_KEYWORD( SELECT );
        ADD_KEYWORD( WHERE );
        ADD_KEYWORD( FROM );
        ADD_KEYWORD( TOP );
        ADD_KEYWORD( LIKE );
        ADD_KEYWORD( ORDER );
        ADD_KEYWORD( BY );
        ADD_KEYWORD( ASC );
        ADD_KEYWORD( DESC );
        ADD_KEYWORD( DISTINCT );
        ADD_KEYWORD( AS );
        ADD_KEYWORD( AND );
        ADD_KEYWORD( OR );
        ADD_KEYWORD( COUNT );
        ADD_KEYWORD( MAX );
        ADD_KEYWORD( MIN );

#undef ADD_KEYWORD

        // operators and symbols
        dict["="] = T_ASSIGN;
        dict[","] = T_COMMAS;
        dict[";"] = T_SEMICOLON;
        dict["*"] = T_ASTERISK;
        dict["("] = T_LPAREN;
        dict[")"] = T_RPAREN;
        dict["=="] = T_EQUAL;
        dict["!="] = T_NOT_EQUAL;
        dict["<"] = T_LESS;
        dict[">"] = T_GREATER;
        dict["<="] = T_LESS_OR_EQUAL;
        dict[">="] = T_GREATER_OR_EQUAL;

        dict["+"] = T_ADD;
        dict["-"] = T_MINUS;
        dict["/"] = T_DIVIDE;
    }

    bool IsIn(const char * token) const
    {
        return dict.find(token) != dict.end();
    }

    int operator [] (const char * token)
    {
        auto it = dict.find(token);

        return (it == dict.end())? LEXERROR : it->second;
    }

    int GetType(const char * token)
    {
        return (*this)[token];
    }

private:
    stdext::hash_map<std::string, int> dict;
};